import "core-js/modules/es.object.from-entries.js";
export function convertLetterToNumber(str) {
  var out = 0,
      len = str.length;

  for (let pos = 0; pos < len; pos++) {
    out += (str.charCodeAt(pos) - 64) * Math.pow(26, len - pos - 1);
  }

  return out;
}
export function toLetters(num) {
  "use strict";

  var mod = num % 26,
      pow = num / 26 | 0,
      out = mod ? String.fromCharCode(64 + mod) : (--pow, 'Z');
  return pow ? toLetters(pow) + out : out;
}
export function parseKey(key = '') {
  let row = key.match(/\d+/g)[0];
  let columnIndex = convertLetterToNumber(key.replace(row, ''));
  let rowIndex = parseInt(row);
  return {
    r: rowIndex - 1,
    c: columnIndex - 1
  };
}
export function useDataGrid({
  url,
  opt = {},
  ...options
} = {}) {
  let state = ZY.T.state({
    loaded: false,
    result: []
  });

  async function req() {
    let lodash = ZY.lodash;
    let [err, res] = await ZY.awaitTo(window.Req.get(url, opt));

    if (err) {
      return Promise.reject(err);
    }

    state.loaded = true;
    res.result.defs = res.result.defs.map(v => {
      v.origin_id = v.id;
      v.id = ZY.rid(6);
      return v;
    });
    res.result.originStr = res.result.origin;
    res.result.origin = ZY.JSON5.parse(res.result.origin)[0];
    res.result.defs = res.result.defs.filter(v => {
      if (v.formServer) {
        return true;
      }

      if (!v.config) {
        return false;
      }

      if (!v.config.fieldName && !v.config.tableName) {
        return false;
      }

      return true;
    }); // console.log( res.result.defs)

    if (options && options.onReady) {
      options.onReady(res);
    }

    let merge = lodash.get(res.result.origin, 'config.merge', {}); // console.log('merge', merge)

    lodash.each(merge, function (item, key) {
      // console.log(item, key)
      item.re = item.r + item.rs;
      item.ce = item.c + item.cs;
      item.cells = [];
    });
    let mergeArr = Object.entries(merge); // console.log(mergeArr)

    let celldata = lodash.get(res.result.origin, 'celldata', []);
    lodash.each(celldata, function (cell) {
      // console.log(cell)
      let letter = toLetters(cell.c + 1) + (cell.r + 1); // let merge_key = cell.r + '_' + cell.c

      for (let [row, c] of mergeArr) {
        if (cell.r >= c.r && cell.r < c.re) {
          if (cell.c >= c.c && cell.c < c.ce) {
            if (!c.config) {
              c.config = cell;
            }

            c.cells.push(cell);
            return;
          }
        }
      }

      let o = {
        id: ZY.rid(6),
        range: letter + ':' + letter,
        content: cell.v.m,
        formServer: true,
        cell: cell
      };
      res.result.defs.push(o);
    });

    for (let [row, cell] of mergeArr) {
      var _o$cell, _o$cell$v;

      // console.log(cell)
      let letter1 = toLetters(cell.c + 1) + (cell.r + 1);
      let letter2 = toLetters(cell.ce) + cell.re;
      let range = letter1 + ':' + letter2;
      let o = {
        id: ZY.rid(6),
        range: letter1 + ':' + letter2,
        rangeArr: [letter1, letter2],
        content: cell.config.v.m,
        formServer: true,
        cell: cell.config,
        isMerge: true
      };

      if (!(o !== null && o !== void 0 && (_o$cell = o.cell) !== null && _o$cell !== void 0 && (_o$cell$v = _o$cell.v) !== null && _o$cell$v !== void 0 && _o$cell$v.bg)) {
        var _options$bg;

        o.cell.v.bg = (_options$bg = options === null || options === void 0 ? void 0 : options.bg) !== null && _options$bg !== void 0 ? _options$bg : '#fff';
      }

      let finded = res.result.defs.find(v => {
        let flag = false;

        if (v.range === range) {
          flag = true;
        } else {
          let v_rangeArr = v.range.split(':');

          if (Array.isArray(v_rangeArr)) {
            v_rangeArr.forEach(item => {
              if (o.rangeArr.includes(item)) {
                flag = true;
              }
            });
          }
        }

        return flag;
      }); // console.log(finded)

      if (finded) {
        finded.cell = cell.config;
        finded.range = o.range;
      } else {
        res.result.defs.push(o);
      }
    }

    res.result.model = {};
    res.result.mergeMap = {};

    function resolveDefPOS(def) {
      def.srangeArr = def.range.split(':');

      if (def.srangeArr[0] === def.srangeArr[1]) {
        def.isSingle = true;
        def.letterSingle = def.srangeArr[0];
      } else {
        res.result.mergeMap[def.srangeArr[0]] = {
          end: def.srangeArr[1]
        };
      }

      def.rangePos = def.srangeArr.map(key => {
        let obj = parseKey(key);

        if (obj) {
          if (obj.r > lastRow) {
            lastRow = obj.r;
          }

          if (obj.c > lastColumn) {
            lastColumn = obj.c;
          }
        }

        return obj;
      });
      def.cArr = def.rangePos.map(v => v.c).sort(function (a, b) {
        return a - b;
      });
      def.rArr = def.rangePos.map(v => v.r).sort(function (a, b) {
        return a - b;
      });

      if (def.isSingle) {
        def.rangePosCell = def.rangePos[0];
      }
    }

    let lastRow = 0;
    let lastColumn = 0;
    lodash.forEach(res.result.defs, function (def) {
      var _def$config, _def$config2, _def$config2$ui;

      let defVal = lodash.get(def, 'config.ui.defVal', undefined);

      if (def !== null && def !== void 0 && (_def$config = def.config) !== null && _def$config !== void 0 && _def$config.fieldName && typeof defVal !== 'undefined') {
        res.result.model[def.config.fieldName] = defVal;
      }

      resolveDefPOS(def);

      if (def !== null && def !== void 0 && (_def$config2 = def.config) !== null && _def$config2 !== void 0 && (_def$config2$ui = _def$config2.ui) !== null && _def$config2$ui !== void 0 && _def$config2$ui.dataSourceType) {
        def.config.ui.enableRemote = true;
      }
    }); // lodash.forEach( res.result.selectDefs, function (def) {
    //   resolveDefPOS(def)
    // })
    // console.log(lastRow, lastColumn)

    res.result.lastRow = lastRow;
    res.result.lastColumn = lastColumn;
    state.result = res.result; // console.timeEnd('111')

    window.__last_grid_result__ = res.result;
  }

  req();

  function getExt() {
    let treeList = ZY.lodash.get(state.result, 'treeList', []);
    let formName = ZY.lodash.get(opt, 'params.formName', '');
    let finded = null;

    if (formName) {
      finded = treeList.find(v => v.formName === formName);
    }

    return finded;
  }

  async function submit(formCtx) {
    let ext = getExt();
    let [isValid, errors, data] = await formCtx.submit();
    let business = [];
    Object.entries(data).forEach(([key, value]) => {
      let def = state.result.defs.find(v => {
        var _v$config;

        let fieldName = v === null || v === void 0 ? void 0 : (_v$config = v.config) === null || _v$config === void 0 ? void 0 : _v$config.fieldName;
        return fieldName === key;
      });

      if (def) {
        business.push({ ...(def === null || def === void 0 ? void 0 : def.config),
          fieldValue: value
        });
      }
    });
    let obj = {
      business,
      ...ext
    };
    return {
      ext,
      isValid,
      errors,
      data,
      obj
    };
  }

  function getResult() {
    var _state$result;

    return (_state$result = state.result) !== null && _state$result !== void 0 ? _state$result : {};
  }

  function mergeArr(arr = []) {
    var _state$result$mergeMa;

    let a = [];
    let map = (_state$result$mergeMa = state.result.mergeMap) !== null && _state$result$mergeMa !== void 0 ? _state$result$mergeMa : {};
    arr.forEach(item => {
      if (map.hasOwnProperty(item.key)) {
        a.push(map[item.key].end);
      }
    });
    return arr.concat(a);
  }

  function getAllCells() {
    let arr = [];
    state.result.defs.forEach(v => {
      if (v.rangeArr[0] === v.rangeArr[1]) {
        arr = arr.concat(v.rangeArr);
      } else {
        // console.log('sdsds', v.rangePos)
        let _a = [];
        let [p1, p2] = v.rangePos;

        for (let c1 = p1.c; c1 <= p2.c; c1++) {
          for (let r1 = p1.r; r1 <= p2.r; r1++) {
            let key = toLetters(c1 + 1) + (r1 + 1); // console.log(key)

            _a.push(key);
          }
        }

        arr = arr.concat(_a);
      }
    });
    let a = [...new Set(arr)]; // console.log(a)

    return a;
  }

  return {
    getAllCells,
    state,
    submit,
    mergeArr,
    getResult,
    getExt,
    req
  };
}
export function useGridBatchSelect(props, ctx, {
  idKey = 'id',
  getAppScrollY = null
} = {}) {
  const {
    watch,
    nextTick,
    reactive
  } = window.vueCompositionAPI;
  let state = reactive({
    selectIdxs: []
  });
  let id = ZY.rid();
  let selector = '.el-table__body-wrapper .el-table__row';
  let relSelector = '';
  let singleData = null;
  let uniqueIds = [];
  let isProgram = false;
  let isNeedWatch = true;

  function tableRowClassName({
    row,
    rowIndex
  }) {
    // console.log('row', row, rowIndex)
    if (!Array.isArray(uniqueIds)) {
      return '';
    }

    let ids = uniqueIds.map(v => v.dataset.uuid); // console.log(ids)

    if (ids.includes(row[idKey])) {
      return 'batch-row--selected';
    } // if (rowIndex === 1) {
    //   return 'warning-row';
    // } else if (rowIndex === 3) {
    //   return 'success-row';
    // }


    return '';
  }

  function tableRowClick(row, column, e) {
    // console.log('row, column, event', isProgram, row, column, event)
    //
    // isProgram = true
    // uniqueIds = []
    if (e.ctrlKey) {
      isNeedWatch = false; // console.log(uniqueIds)

      uniqueIds.push({
        dataset: {
          uuid: row[idKey]
        }
      });
      uniqueIds = ZY.lodash.uniqBy(uniqueIds, 'dataset.uuid');
      singleData = null;
      nextTick(() => {
        isNeedWatch = true;
      });
      return;
    }

    if (!isProgram) {
      isNeedWatch = false; // state.selectIdxs.splice(0)

      uniqueIds = [{
        dataset: {
          uuid: row[idKey]
        }
      }]; // singleData = {row}

      singleData = null;
      nextTick(() => {
        isNeedWatch = true;
      });
    }
  }

  function getSelectedUUIDS() {
    if (uniqueIds.length < 1 && singleData) {
      return [singleData.row[idKey]];
    } // console.log(singleData)


    return uniqueIds.map(v => v.dataset.uuid);
  }

  function getSelectedContents() {
    // console.log(singleData)
    if (uniqueIds.length < 1 && singleData) {
      return [singleData.row];
    }

    return uniqueIds.map(v => {
      if (v.content) {
        return ZY.JSON5.parse(v.content);
      }

      return undefined;
    });
  }

  function cancelSelect() {
    isProgram = true;
    isNeedWatch = false;
    state.selectIdxs.splice(0);
    uniqueIds = [];
    singleData = null;
    document.querySelector(selector).click();
    let elTableCtx = ctx.refs.zTable.$_getTable(); // console.log(document.querySelector('.el-table__body-wrapper'))
    // ctx.refs.table.$refs.table.setCurrentRow()

    elTableCtx === null || elTableCtx === void 0 ? void 0 : elTableCtx.setCurrentRow();
    nextTick(() => {
      isNeedWatch = true;
      isProgram = false;
    });
  }

  function getScrollY() {
    if (getAppScrollY) {
      return getAppScrollY();
    }

    return 0;
  }

  let tool = {
    state,
    id,
    selector,
    getScrollY,
    tableRowClassName,
    relSelector,
    cancelSelect,
    getSelectedUUIDS,
    getSelectedContents,
    tableRowClick
  };
  watch(() => state.selectIdxs, function (newVal, oldVal) {
    // console.log(newVal, oldVal, isNeedWatch)
    if (isNeedWatch) {
      uniqueIds = ZY.lodash.uniqBy(state.selectIdxs, 'dataset.uuid');
      singleData = null; // console.log(uniqueIds)
      // console.log(    ctx.refs.table.$refs.table)
      // ctx.refs.table.$refs.table.doLayout()

      nextTick(() => {
        isProgram = true;
        document.querySelector(selector).click(); // console.log(ctx.refs.searchTable.getElTable())

        let elTableCtx = ctx.refs.zTable.$_getTable(); // console.log(document.querySelector('.el-table__body-wrapper'))
        // ctx.refs.table.$refs.table.setCurrentRow()

        elTableCtx === null || elTableCtx === void 0 ? void 0 : elTableCtx.setCurrentRow();
        nextTick(() => {
          isProgram = false;
        });
      });
    }
  });
  return tool;
}
export function useArrTool(keys = [], current = '') {
  let arrTool = {};
  arrTool.state = ZY.T.state({
    current: current,
    keys: keys
  });

  function checkLastCurrent(v) {
    if (arrTool.state.current === v) {
      arrTool.state.current = ZY.lodash.nth(arrTool.state.keys, -1);
    }
  }

  arrTool.append = function (v) {
    arrTool.state.keys.push(v);

    if (!arrTool.state.current) {
      arrTool.state.current = v;
    }
  };

  function rm(v, args) {
    // console.log(args)
    arrTool.state.keys.splice(...args);
    checkLastCurrent(v);
  }

  arrTool.delByValye = function (v, len = 1) {
    let index = arrTool.state.keys.findIndex(a => a === v);

    if (index > -1) {
      // console.log('delByValye', v, index)
      arrTool.state.keys.splice(index, len); // let nIndex = index - 1
      // if (nIndex > -1) {
      //   arrTool.state.current = arrTool.state.keys[nIndex]
      // }

      if (arrTool.state.current === v) {
        arrTool.state.current = arrTool.state.keys[index - 1];
      }
    }
  };

  arrTool.remove = function (...args) {
    let v = ZY.lodash.nth(arrTool.state.keys, args[0]); // console.log(arrTool.state.current, v)

    rm(v, args);
  };

  arrTool.handleChange = function (e) {
    // console.log('handleChange', e.target.selected)
    arrTool.state.current = e.target.selected;
  };

  return arrTool;
}
export function useFetchDataSource() {
  let cachedData = [];

  function initReq(apiConfig, {
    token = ''
  } = {}) {
    let {
      config = {},
      ui,
      url
    } = apiConfig;
    let reqOption = {
      method: 'get',
      url: url
    };

    if (ui.dataSourceType === '参数') {
      if (Array.isArray(ui.customParamObject)) {
        cachedData = ui.customParamObject.map(v => {
          v._value = v.value;

          if (!v.hasOwnProperty('label')) {
            v.label = v.key;
          } // if (!v.hasOwnProperty('value')) {
          //   v.value = v.value
          // }


          return v;
        });
      }
    }

    if (ui.dataSourceType === '接口') {
      reqOption.url = ui.interfacePath;
      reqOption.method = ui.interfaceMethods;
    }

    if (ui.dataSourceType === '字典') {
      reqOption.url = `/zy-boot/form/getDictItem?id=${ui.dataSource}`;
    }

    let ajaxOption = {
      headers: {
        ['X-Access-Token']: token // ['X-Random']: ZY.rid()

      }
    };
    return [reqOption, ajaxOption];
  }

  function getRes(res = {}) {
    var _res$result;

    let ret = [];

    if (res !== null && res !== void 0 && (_res$result = res.result) !== null && _res$result !== void 0 && _res$result.options) {
      var _res$result$options, _res$result2;

      ret = (_res$result$options = (_res$result2 = res.result) === null || _res$result2 === void 0 ? void 0 : _res$result2.options) !== null && _res$result$options !== void 0 ? _res$result$options : [];
    } else if (res !== null && res !== void 0 && res.result) {
      ret = res.result;
    }

    return ret;
  }

  async function req({
    reqOption,
    ajaxOption
  } = {}) {
    if (Array.isArray(cachedData) && cachedData.length > 0) {
      return cachedData;
    }

    if (reqOption.url) {
      let r = ZY.rid();

      if (reqOption.url.includes('?')) {
        r = reqOption.url + '&v=' + r;
      } else {
        r = reqOption.url + '?v=' + r;
      }

      if (reqOption.method === 'get') {
        let [err, res] = await ZY.awaitTo(window.Req.get(r, ajaxOption)); // console.log(cachedData, reqOption, res)

        return getRes(res);
      }

      if (reqOption.method === 'post') {
        let [err, res] = await ZY.awaitTo(window.Req.post(r, {}, ajaxOption));
        return getRes(res);
      }
    }
  }

  return {
    req,
    initReq,
    getRes
  };
}
export let SortByIndex = {
  sortArr(_arr = [], obj_path = 'ui.area') {
    let arr = [];
    arr = _arr.sort(function (a, b) {
      let area1 = ZY.lodash.get(a, obj_path, '');
      let area2 = ZY.lodash.get(b, obj_path, ''); // console.log(area1, area2)

      if (!area1 || !area2) {
        return 0;
      }

      const isNumber = v => (+v).toString() === v;

      const aPart = area1.match(/\d+|\D+/g);
      const bPart = area2.match(/\d+|\D+/g);
      let i = 0;
      let len = Math.min(aPart.length, bPart.length);

      while (i < len && aPart[i] === bPart[i]) {
        i++;
      }

      if (i === len) {
        return aPart.length - bPart.length;
      }

      if (isNumber(aPart[i]) && isNumber(bPart[i])) {
        return aPart[i] - bPart[i];
      }

      return aPart[i].localeCompare(bPart[i]); // return 0
    }); // console.log('sort', arr)

    return arr;
  },

  sort(p = {}, obj_path = 'ui.area') {
    let arr = [];
    arr = Object.entries(p.properties).sort(function (a, b) {
      let area1 = ZY.lodash.get(a[1], obj_path, '');
      let area2 = ZY.lodash.get(b[1], obj_path, ''); // console.log(area1, area2)

      if (!area1 || !area2) {
        return 0;
      }

      const isNumber = v => (+v).toString() === v;

      const aPart = area1.match(/\d+|\D+/g);
      const bPart = area2.match(/\d+|\D+/g);
      let i = 0;
      let len = Math.min(aPart.length, bPart.length);

      while (i < len && aPart[i] === bPart[i]) {
        i++;
      }

      if (i === len) {
        return aPart.length - bPart.length;
      }

      if (isNumber(aPart[i]) && isNumber(bPart[i])) {
        return aPart[i] - bPart[i];
      }

      return aPart[i].localeCompare(bPart[i]); // return 0
    }); // console.log('sort', arr)

    p.properties = Object.fromEntries(arr);
  },

  deepSort(p) {
    ZY.lodash.each(p.properties, function (item, key) {
      if (item.type === 'object') {
        SortByIndex.sort(item);
      } else if (item.type === 'array') {
        // console.log('deepSort', item)
        SortByIndex.sort(item.items);
      }
    });
  }

};
/**
 * 创建简单form创建起
 * @returns {{init: ((function(*=): Promise<void>)|*), state, properties: {}}}
 */

export function createEasyForm({
  handleProperties,
  request = window.Req
} = {}) {
  let formCtx = {};
  let state = ZY.T.state({
    style: {},
    loading: false,
    inited: false
  });
  let properties = {}; // if (!urlMap) {
  //   urlMap = {
  //     add: url,
  //     edit: url
  //   }
  // }

  let option = {};

  async function init(apiAddress = '', {
    autoLoad = true
  } = {}) {
    if (!apiAddress) {
      return;
    }

    let [err, res] = await ZY.awaitTo(request.get(apiAddress));
    let obj = {
      properties: res.result
    }; // SortByIndex.sort(obj)
    // SortByIndex.deepSort(obj)

    let r = obj.properties; // console.log(Object.keys(r))

    if (handleProperties) {
      r = handleProperties(r);
    }

    tool.properties = r;
    await ZY.sleep(300);
    state.inited = true;
    option.autoLoad = autoLoad;
  }

  async function onSubmit(model, scope = {}) {
    // console.log('onSubmit', model, scope)
    if (option.autoSubmit) {
      let method = request.post;
      let reqUrl = option.url;
      let sms = {
        data: model
      };

      if (scope !== null && scope !== void 0 && scope.IS_EDIT) {
        method = request.put;
        reqUrl = option.editUrl;
      }

      let [err, res] = await ZY.awaitTo(method(reqUrl, sms, {}));

      if (!err) {
        if (tool.onSubmitSuccess) {
          tool.onSubmitSuccess(res);
        }
      }
    }
  }

  function setOption(v) {
    option = v;
  }

  async function load(url) {
    if (url) {
      state.loading = true;
      let [err, res] = await ZY.awaitTo(request.get(url, {}, {}));
      state.loading = false;

      if (err) {
        return;
      }

      if (formCtx.form) {
        formCtx.form.importData(res === null || res === void 0 ? void 0 : res.result.data);
      }
    }
  }

  async function onReady(e) {
    // console.log('onReady', option)
    formCtx = e;

    if (option.autoLoad) {
      load(option.detailUrl);
    }

    if (tool.onFormReady) {
      tool.onFormReady();
    }
  }

  let tool = {
    state,
    onReady,
    onSubmit,
    setOption,
    load,
    properties,
    init
  };
  return tool;
}